/**
  * <br>JAVACC DEMO 1.0<br>
  * @copy right ius company All rights reserved.<br>
  * <br>
  * @Package com.ius.database.exception
*/
package com.apache.database.exception;

import org.springframework.core.NestedRuntimeException;

/**
  * description: 数据层异常类
  * @author Hou DaYu 创建时间：上午09:56:51
  */
@SuppressWarnings("serial")
public class DaoAccessException extends RuntimeException {

	/**
	 * Construct a <code>DaoAccessException</code> with the specified detail message.
	 * @param msg the detail message
	 */
	public DaoAccessException(String msg) {
		super(msg);
	}

	/**
	 * Construct a <code>DaoAccessException</code> with the specified detail message
	 * and nested exception.
	 * @param msg the detail message
	 * @param cause the nested exception
	 */
	public DaoAccessException(String msg, Throwable cause) {
		super(msg, cause);
	}

	/**
	 * Return the detail message, including the message from the nested exception
	 * if there is one.
	 */
	public String getMessage() {
		return buildMessage(super.getMessage(), getCause());
	}

	/**
	 * 检索此异常根原因
	 * @return the innermost exception, or <code>null</code> if none
	 */
	public Throwable getRootCause() {
		Throwable rootCause = null;
		Throwable cause = getCause();
		while (cause != null && cause != rootCause) {
			rootCause = cause;
			cause = cause.getCause();
		}
		return rootCause;
	}

	/**
	 * 检索此异常的具体的原因.
	 * @return the most specific cause (never <code>null</code>)
	 */
	public Throwable getMostSpecificCause() {
		Throwable rootCause = getRootCause();
		return (rootCause != null ? rootCause : this);
	}

	/**
	 * 检查异常是否包含一个异常给定类型的:
	 * @param exType the exception type to look for
	 * @return whether there is a nested exception of the specified type
	 */
	public boolean contains(Class exType) {
		if (exType == null) {
			return false;
		}
		if (exType.isInstance(this)) {
			return true;
		}
		Throwable cause = getCause();
		if (cause == this) {
			return false;
		}
		if (cause instanceof NestedRuntimeException) {
			return ((NestedRuntimeException) cause).contains(exType);
		} else {
			while (cause != null) {
				if (exType.isInstance(cause)) {
					return true;
				}
				if (cause.getCause() == cause) {
					break;
				}
				cause = cause.getCause();
			}
			return false;
		}
	}

	/**
	 * Build a message for the given base message and root cause.
	 * @param message the base message
	 * @param cause the root cause
	 * @return the full exception message
	 */
	private String buildMessage(String message, Throwable cause) {
		if (cause != null) {
			StringBuilder sb = new StringBuilder();
			if (message != null) {
				sb.append(message).append("; ");
			}
			sb.append("nested exception is ").append(cause);
			return sb.toString();
		} else {
			return message;
		}
	}
}
